functor Dot (S : DOT_STRUCTS) : DOT =
struct
  open S
  
  structure Content =
  struct
    datatype t 
      = T of {head : string,
              tail : string} list
    
    fun toString (T l) =
        let fun cook l =
                case l
                 of [] => ""
                  | {head, tail} :: xs =>
                    String.concat ["\t", "\"", head, "\"", " -> ", "\"", tail, "\"", ";\n",
                                   cook xs]
        in  cook l
        end
  end
  
  datatype t
    = T of {name : string,
            size : {width : int, height : int},
            node : {color : string, style : string},
            contents : Content.t}
         
  fun toString (T {name,
                   size = {width, height},
                   node = {color, style},
                   contents}) =
      let val contents = Content.toString (contents)
      in  String.concat ["digraph ", name, "{\n",
                         "\tsize = ", "\"", Int.toString width, ", ", Int.toString height, "\"", ";\n",
                         "\tnode [color=", color, ", style=", style, "];\n",
                         contents,
                         "}\n"]
      end
      
  fun getName (T {name, ...}) = name
      
  fun outputFile (t) =
      let val s = toString (t)
          val name = getName t
          val f = TextIO.openOut (name^".dot")
          val _ = TextIO.output (f, s)
          val _ = TextIO.closeOut f
      in  ()
      end 
end

structure Dot = Dot ();
